home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Control / Control_Main.c < prev    next >
C/C++ Source or Header  |  1996-11-05  |  60KB  |  2,033 lines

  1. /*
  2.  
  3.    HBBS (C) 1995/6 Hydra/LSD - All Rights Reserved!
  4.  
  5.    If you are reading this source and make *ANY* change or fix or whatever
  6.    then please send a copy to me at the following address...
  7.  
  8.    D.Clifton, 9 Shires Copse, Southbourne, Bournemouth, Dorset, BH6 4AL, ENGLAND!
  9.  
  10.    All Suggestions are most welcome as if *you* think something needs changing
  11.    then it probably does,  this program is supposed to be designed for the
  12.    user, not the programmer of it!!
  13.  
  14.    Thanks..
  15.  
  16.    Note: if you want a better KS3.0 only version then #define KS30 otherwise #define KS20..
  17.    and if you want to run cpr on the node program then #define DEBUGNODE
  18.  
  19.  
  20.    NGad[       -> NewGad[
  21.    FreeImages; -> FreeImages();
  22.  
  23. */
  24.  
  25.  
  26. /*
  27.  
  28.   create linked list of TimeAccessData at startup
  29.  
  30. */
  31.  
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <time.h>
  37.  
  38. #include <exec/types.h>
  39. #include <exec/memory.h>
  40. #include <dos/dos.h>
  41. #include <dos/dostags.h>
  42. #include <dos/dosextens.h>
  43. #include <dos/filehandler.h>
  44. #include <intuition/screens.h>
  45. #include <intuition/intuition.h>
  46. #include <intuition/gadgetclass.h>
  47. #include <libraries/locale.h>
  48. #include <libraries/reqtools.h>
  49. #include <libraries/gadtools.h>
  50. #include <diskfont/diskfont.h>
  51. #include <utility/utility.h>
  52. #include <graphics/gfxbase.h>
  53. #include <graphics/scale.h>
  54. #include <workbench/workbench.h>
  55. #include <clib/locale_protos.h>
  56. #include <clib/exec_protos.h>
  57. #include <clib/wb_protos.h>
  58. #include <clib/intuition_protos.h>
  59. #include <clib/gadtools_protos.h>
  60. #include <clib/graphics_protos.h>
  61. #include <clib/utility_protos.h>
  62. #include <clib/diskfont_protos.h>
  63. #include <clib/alib_protos.h>
  64. #include <clib/dos_protos.h>
  65. #include <clib/reqtools_protos.h>
  66.  
  67. #include <wb2cli.h>  /* for the correct PATH settings when run from WB */
  68.  
  69.  
  70. #include "/common/release.h"
  71. char *versionstr="$VER: Control "RELEASE_STR;
  72.  
  73. #ifdef __SASC
  74. int CXBRK(void) { return(0); }
  75. int _CXBRK(void) { return(0); }
  76. void chkabort(void) {}
  77. #endif
  78.  
  79. #include "ControlGUI.h" // gui prototypes and external variables.
  80.  
  81. /* Main Stuff! */
  82.  
  83. #define MAIN
  84.  
  85. #include "/common/types.h"
  86. #include "/common/defines.h"
  87. #include "/common/errors.h"
  88. #include "/common/files.h"
  89. #include "/common/options.h"
  90. #include "/common/structures.h"
  91. #include "/common/strings.h"
  92.  
  93. #include "/library/hbbscommon_protos.h"
  94. #include "/library/hbbscommon_pragmas.h"
  95.  
  96. struct ReqToolsBase *ReqToolsBase;
  97. extern struct DosLibrary *DOSBase;
  98. struct Window *OldWindowPtr;
  99. struct Library *HBBSCommonBase=NULL;
  100. struct ScreenInfoData NewScr;
  101.  
  102. char StatusText[80];
  103.  
  104. UWORD CtrlScrnCoolPens[]=
  105. {
  106.   0+8,1+8,1+8,2+8,1+8,3+8,2+8,0+8,2+8,1+8,2+8,1+8,65535
  107. };
  108.  
  109. /*
  110.   DETAILPEN,0+8,
  111.   BLOCKPEN,1+8,
  112.   TEXTPEN,1+8,
  113.   SHINEPEN,2+8,
  114.   SHADOWPEN,1+8,
  115.   FILLPEN,3+8,
  116.   FILLTEXTPEN,2+8,
  117.   BACKGROUNDPEN,0+8,
  118.   HIGHLIGHTTEXTPEN,2+8,
  119.   BARDETAILPEN,1+8,
  120.   BARBLOCKPEN,2+8,
  121.   BARTRIMPEN,1+8,
  122.  
  123. #define DETAILPEN        (0x0000)
  124. #define BLOCKPEN         (0x0001)
  125. #define TEXTPEN          (0x0002)
  126. #define SHINEPEN         (0x0003)
  127. #define SHADOWPEN        (0x0004)
  128. #define FILLPEN          (0x0005)
  129. #define FILLTEXTPEN      (0x0006)
  130. #define BACKGROUNDPEN    (0x0007)
  131. #define HIGHLIGHTTEXTPEN (0x0008)
  132. #define BARDETAILPEN     (0x0009)
  133. #define BARBLOCKPEN      (0x000A)
  134. #define BARTRIMPEN       (0x000B)
  135.  
  136.  
  137.  
  138. */
  139.  
  140. UWORD ColourArray[]=
  141. {
  142.   0x0000,
  143.   0x0F00,
  144.   0x00F0,
  145.   0x0FF0,
  146.   0x000F,
  147.   0x0F0F,
  148.   0x00FF,
  149.   0x0FFF,
  150.   0x0999,
  151.   0x0000,
  152.   0x0FFF,
  153.   0x057A,
  154. };
  155.  
  156. // global vars
  157.  
  158. UWORD offx;
  159. UWORD offy;
  160. WORD last_x=0;
  161. WORD last_y=0;
  162. LONG last_sec=0;
  163. LONG last_mic=0;
  164.  
  165. BOOL CfgOpen=FALSE;
  166.  
  167. struct Process *CtrlProc=NULL;
  168. struct BBSGlobalData *BBSGlobal=NULL;
  169. struct TextFont *HBBSFont;
  170.  
  171.  
  172. #ifdef KS20
  173. UWORD LastNodeClicked=0;  //due to GT_GetGadgetAttrs() being V39+ only we have to
  174.                           // make a note of the last node number clicked on in
  175.                           // the Nodes Listview! Argh!
  176. UWORD LastCycleClicked=0; // (and in the List Cycle Gadget Clicked..)
  177. #endif
  178.  
  179. //defines for struct BBSGlobalData
  180.  
  181. UBYTE *FILE_SCRMODEPREFS           = "HBBS:System/Data/CtrlScrPrefs.CFG";
  182.  
  183. UBYTE *OPT_BBS_BBSName             = "BBSName",
  184.       *OPT_BBS_BBSSerial           = "BBSSerial",
  185.       *OPT_BBS_BBSLocation         = "BBSLocation",
  186.       *OPT_BBS_BBSCountry          = "BBSCountry",
  187.       *OPT_BBS_BBSGroup            = "BBSGroup",
  188.       *OPT_BBS_BBSNodes            = "BBSNodes",
  189.       *OPT_BBS_SysopAccount        = "SysopAccount",
  190.       *OPT_BBS_Drive               = "Drive",
  191.       *OPT_BBS_BBSDrive            = "BBSDrive",
  192.       *OPT_BBS_MinFreeSpace        = "MinFreeSpace",
  193.       *OPT_BBS_NoFreeSpaceScript   = "NoFreeSpaceScript",
  194.       *OPT_BBS_ButtonName          = "ButtonName",
  195.       *OPT_BBS_ButtonCMD           = "ButtonCMD",
  196.       *OPT_BBS_HideScreen          = "HideScreen",
  197.       *OPT_BBS_ErrorLogFile        = "ErrorLogFile",
  198.       *OPT_BBS_PubScreenName       = "PubScreenName",
  199.       *OPT_BBS_UsePubScreen        = "UsePubScreen",
  200.       *OPT_BBS_ScrModeID           = "ScrModeID",
  201.       *OPT_BBS_ScrWidth            = "ScrWidth",
  202.       *OPT_BBS_ScrHeight           = "ScrHeight",
  203.       *OPT_BBS_ScrDepth            = "ScrDepth",
  204.       *OPT_BBS_UserDataFileName    = "UserDataFileName",
  205. //      *OPT_BBS_NewUserAccessLevel  = "NewUserAccessLevel",
  206.       *OPT_BBS_MaxUsernameAttempts = "MaxUsernameAttempts",
  207.       *OPT_BBS_MaxPasswordAttempts = "MaxPasswordAttempts",
  208.       *OPT_BBS_MinPasswordLength   = "MinPasswordLength",
  209.       *OPT_BBS_LanguageName        = "LanguageName",
  210.       *OPT_BBS_LanguageExtn        = "LanguageExtn",
  211.       *OPT_BBS_EditorCMD           = "EditorCMD",
  212.       *OPT_BBS_CopyBufferSize      = "CopyBufferSize";
  213.  
  214. UBYTE *OPT_CONFL_Conferences       = "Conferences",
  215.       *OPT_CONFL_ConfPath          = "ConfPath";
  216. //      *OPT_CONFL_NewUserConf       = "NewUserConf";
  217.  
  218. UBYTE *OPT_CONF_ConfName           = "ConfName",
  219.       *OPT_CONF_ConfActive         = "ConfActive",
  220.       *OPT_CONF_ConfAccess         = "ConfAccess",
  221.       *OPT_CONF_HoldFileList       = "HoldFileList",
  222.       *OPT_CONF_HoldFiles          = "HoldFiles",
  223.       *OPT_CONF_BadFileList        = "BadFileList",
  224.       *OPT_CONF_BadFiles           = "BadFiles",
  225.       *OPT_CONF_PartUpload         = "PartUpload",
  226.       *OPT_CONF_FileList           = "FileList",
  227.       *OPT_CONF_Upload             = "Upload",
  228.       *OPT_CONF_Download           = "Download",
  229.       *OPT_CONF_MaxDIZLines        = "MaxDIZLines",
  230.       *OPT_CONF_MenuPrompt         = "MenuPrompt",
  231.       *OPT_CONF_AutoMailScan       = "AutoMailScan",
  232.       *OPT_CONF_ConfPassWD         = "ConfPassWD",
  233.       *OPT_CONF_UserAllowed        = "UserAllowed",
  234.       *OPT_CONF_KeepDIZWithFile    = "KeepDIZWithFile";
  235.  
  236. UBYTE *OPT_LLIST_LEVEL             = "Level",
  237.       *OPT_LLIST_LEVELNAME         = "Level_Name",
  238.       *OPT_LLIST_CONFACS           = "ConfAcs";
  239.  
  240. #include "/common/Shared.c"
  241.  
  242. extern UWORD    CtrlScrndefpens;
  243.  
  244. extern UWORD   CtrlScrnColors[];
  245.  
  246. void About( void )
  247. {
  248.   char buffer[1024];
  249.  
  250.   sprintf(buffer,"HydraBBS %s (C) 1995 Deluxe Software Ltd.\n\n"
  251. #ifdef BETA
  252.                  "BETA VERSION, DO NOT SPREAD!\n\n"
  253. #endif
  254.                  "HBBS is a cool BBS System programed with users and sysops in mind\n"
  255.                  "unlike the ageing LAmiExpress which it is designed to replace.\n\n"
  256.                  "This software is SHAREWARE, if you use it then send a registration\n"
  257.                  "fee of £20 (UK Pounds Sterling) made Payable to D.Clifton\n\n"
  258.                  "To Deluxe Software Ltd, 9 Shires Copse, Bournemouth, Dorset, BH6 4AL, ENGLAND\n\n"
  259.                  "And you'll receive telephone support and the FULL Source Code, *and*\n"
  260.                  "you'll get all the updates and new doors programmed by as and when they\n"
  261.                  "are released.  See the docs for more info!\n\n"
  262.                  "To contact the author write to the above address, or e-mail dominicc@dircon.co.uk\n\n"
  263.                  "Note: NOTHING IS DISABLED OR CUT-DOWN THIS ISTHE FULL THING!\n",versionstr);
  264.   HBBS_rterror(buffer);
  265. }
  266.  
  267. void PrintList( struct List *list)
  268. {
  269.   struct Node *node;
  270.   for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
  271.   {
  272.     puts(node->ln_Name);
  273.   }
  274. }
  275.  
  276.  
  277.  
  278. BOOL AllNodesShut( void )
  279. {
  280.   short NodesShut=0;
  281.   struct NodeData *nd;
  282.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  283.   {
  284.     if (nd->Status==STAT_CLOSED) NodesShut++;
  285.   }
  286. //  printf("shutcount = %d, nodes = %d\n",NodesShut,BBSGlobal->BBSNodes);
  287.   if (NodesShut==BBSGlobal->BBSNodes) return(TRUE);
  288.   return(FALSE);
  289. }
  290.  
  291. struct Screen *OpenCtrlScrn(void)
  292. {
  293.   struct Screen *NewScrn;
  294.  
  295.   if (NewScrn=OpenScreenTags(NULL,    (SA_Title),(ULONG)"HBBS Main Control Screen (C) 1995 Hydra of LSD!",
  296.     (SA_PubName),(ULONG)str_CtrlScrnName,
  297.     (SA_Left)    ,0,
  298.     (SA_Top)     ,0,
  299.     (SA_Width)   ,BBSGlobal->ScreenInfo.ScrWidth,
  300.     (SA_Height)  ,BBSGlobal->ScreenInfo.ScrHeight,
  301.     (SA_DisplayID),BBSGlobal->ScreenInfo.ScrModeID,
  302.     (SA_Depth)   ,BBSGlobal->ScreenInfo.ScrDepth,
  303.     (SA_Overscan),1,
  304.     (SA_Font),(ULONG)&HBBS8066,
  305.     (SA_Behind),1,
  306.     (SA_Quiet),0,
  307.     (SA_ShowTitle),1,
  308.     (SA_AutoScroll),1,
  309.     (SA_FullPalette),1,
  310. //    (SA_ErrorCode),(ULONG)(&CtrlScrnError),
  311.     (SA_Pens), BBSGlobal->ScreenInfo.ScrDepth<4 ? (ULONG)&CtrlScrndefpens : (ULONG)&CtrlScrnCoolPens,
  312.     (SA_Colors),(ULONG)CtrlScrnColors,
  313.     (TAG_DONE)))
  314.   {
  315.     if (BBSGlobal->ScreenInfo.ScrDepth>=4)
  316.     {
  317.       LoadRGB4(&NewScrn->ViewPort,ColourArray,12);
  318.       SetAPen(&NewScrn->RastPort,8);
  319.       Flood(&NewScrn->RastPort,1,0,NewScrn->WBorTop+4);
  320.     }
  321.   }
  322.   return(NewScrn);
  323. }
  324.  
  325. BOOL PickScreen( void )
  326. {
  327.   BOOL retval=FALSE;
  328.   struct rtScreenModeRequester *scrmodereq;
  329.   char NewScrName[26];
  330.  
  331.   if (rtEZRequest("Screen Type ?","Custom|Public",NULL,NULL,NULL)==1)
  332.   {
  333.     if (scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  334.     {
  335.       if (rtScreenModeRequest (scrmodereq, "Select Screen mode:",RTSC_Flags,SCREQF_GUIMODES | SCREQF_DEPTHGAD | SCREQF_SIZEGADS,
  336.                                                                  RT_Window,Ctrl,
  337.                                                                  RTSC_MinHeight,200,
  338.                                                                  RTSC_MinWidth,640,
  339.                                                                  RTSC_MinDepth,2,
  340.                                                                  RTSC_MaxDepth,4,
  341.  
  342.                                                                  TAG_END))
  343.       {
  344.         NewScr.ScrModeID=scrmodereq->DisplayID;
  345.         NewScr.ScrHeight=scrmodereq->DisplayHeight;
  346.         NewScr.ScrWidth=scrmodereq->DisplayWidth;
  347.         NewScr.ScrDepth=scrmodereq->DisplayDepth;
  348.         NewScr.UsePubScreen=FALSE;
  349.         FreeAndSet(&NewScr.PubScreenName,str_CtrlScrnName);
  350.         retval=TRUE;
  351.       }
  352.       rtFreeRequest(scrmodereq);
  353.     }
  354.   }
  355.   else              // *C* 24-05-1996!
  356.   {
  357.     strcpy(NewScrName,BBSGlobal->ScreenInfo.PubScreenName);
  358.     if (rtGetString (NewScrName, 25, "Enter Screen Name", NULL,RT_Window,Ctrl, TAG_END))
  359.     {
  360.       FreeAndSet(&NewScr.PubScreenName,NewScrName);
  361.       NewScr.UsePubScreen=TRUE;
  362.       retval=TRUE;
  363.     }
  364.   }
  365.   return(retval);
  366. }
  367.  
  368. BOOL LoadScreenPrefs( void )
  369. {
  370.   struct CfgFileData *ScrCfg;
  371.   BOOL OK=FALSE;
  372.  
  373.   if (ScrCfg=HBBS_LoadConfig(FILE_SCRMODEPREFS,LCFG_NONE))
  374.   {
  375.     HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.PubScreenName,VTYPE_STRING,OPT_BBS_PubScreenName,OPT_SINGLE);
  376.     HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.UsePubScreen,VTYPE_BOOL,OPT_BBS_UsePubScreen,OPT_SINGLE);
  377.  
  378.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.ScrModeID,VTYPE_BIGNUM,OPT_BBS_ScrModeID,OPT_SINGLE))
  379.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.ScrHeight,VTYPE_BIGNUM,OPT_BBS_ScrHeight,OPT_SINGLE))
  380.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.ScrWidth,VTYPE_BIGNUM,OPT_BBS_ScrWidth,OPT_SINGLE))
  381.     if (HBBS_GetSetting(ScrCfg,(void *)&BBSGlobal->ScreenInfo.ScrDepth,VTYPE_BIGNUM,OPT_BBS_ScrDepth,OPT_SINGLE)) OK=TRUE;
  382.  
  383.     HBBS_FlushConfig(ScrCfg);
  384.   }
  385.   else
  386.   {
  387.     HBBS_rterror("Use the \"Select_Mode\" Utility to setup a screenmode!");
  388.   }
  389.   return(OK);
  390. }
  391.  
  392. void SaveScreenPrefs( void )
  393. {
  394.   struct CfgFileData *ScrCfg;
  395.   char params[30];
  396.   if (ScrCfg=HBBS_CreateConfig((FILE_SCRMODEPREFS)))
  397.   {
  398.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_PubScreenName,BBSGlobal->ScreenInfo.PubScreenName);
  399.     if (BBSGlobal->ScreenInfo.UsePubScreen)
  400.     {
  401.       HBBS_AddCfgItem(ScrCfg,OPT_BBS_UsePubScreen,"YES");
  402.     }
  403.     else
  404.     {
  405.       HBBS_AddCfgItem(ScrCfg,OPT_BBS_UsePubScreen,"NO");
  406.     }
  407.     sprintf(params,"%d",BBSGlobal->ScreenInfo.ScrModeID);
  408.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrModeID,params);
  409.     sprintf(params,"%d",BBSGlobal->ScreenInfo.ScrHeight);
  410.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrHeight,params);
  411.     sprintf(params,"%d",BBSGlobal->ScreenInfo.ScrWidth);
  412.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrWidth,params);
  413.     sprintf(params,"%d",BBSGlobal->ScreenInfo.ScrDepth);
  414.     HBBS_AddCfgItem(ScrCfg,OPT_BBS_ScrDepth,params);
  415.  
  416.     if (!HBBS_SaveConfig(ScrCfg))
  417.     {
  418.       HBBS_rterror("Error Saving Screenmode Prefs!");
  419.     }
  420.     HBBS_FlushConfig(ScrCfg);
  421.   }
  422. }
  423.  
  424. void UpdateInfoLists( void )
  425. {
  426.   struct NodeData *nd;
  427.  
  428.   // *?* should we set gadgetatrs() the cycle gadget just to make sure.. ?
  429.  
  430.  
  431.   // set the list to be BLANK
  432.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,NULL,TAG_DONE);
  433.  
  434.   if (nd=HBBS_NodeDataPtr(LastNodeClicked)) // code contains number of listview selected
  435.   {
  436.     if ((nd->Status==STAT_ONLINE) || (nd->Status==STAT_READY))
  437.     {
  438.       switch (LastCycleClicked)
  439.       {
  440.         case 0: // Last Callers
  441.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Callers,TAG_DONE);
  442.           break;
  443.         case 1: // Last Downloads
  444.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Downloads,TAG_DONE);
  445.           break;
  446.         case 2: // Last Uploads
  447.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Uploads,TAG_DONE);
  448.           break;
  449.         case 3: // Last Pagers
  450.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Pagers,TAG_DONE);
  451.           break;
  452.         case 4: // Last Fails
  453.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_PWFails,TAG_DONE);
  454.           break;
  455.         case 5: // Last Carrier
  456.           GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,nd->Last_Carrier,TAG_DONE);
  457.           break;
  458.       }
  459.     }
  460.   }
  461. }
  462.  
  463. void updategadgets( void )
  464. {
  465.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Labels,BBSGlobal->NodeList,GTLV_Top,0,TAG_DONE);
  466.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV3_Commands],Ctrl,NULL,GTLV_Labels,BBSGlobal->ButtonName,GTLV_Top,0,TAG_DONE);
  467.   UpdateInfoLists();
  468. }
  469.  
  470. // small routing to check that all the windows on a screen have been closed..
  471.  
  472. void CloseAllWindows(struct Screen *Scr)
  473. {
  474.   if (!BBSGlobal->ScreenInfo.UsePubScreen)
  475.   {
  476.     if ((Scr) && (Scr->FirstWindow))
  477.     {
  478.       while (Scr->FirstWindow->NextWindow)
  479.       {
  480.         rtEZRequest("Please Close All Windows Before Clicking OK","OK",NULL,NULL,NULL);
  481.       }
  482.     }
  483.   }
  484. }
  485.  
  486. void CloseTheScreen( void )
  487. {
  488.   if (BBSGlobal->ScreenInfo.Scr)
  489.   {
  490.     if (CfgOpen)
  491.     {
  492.       CloseCtrlCfgWindow();
  493.       CfgOpen=FALSE;
  494.     }
  495.     CloseAllWindows(BBSGlobal->ScreenInfo.Scr);
  496.  
  497.     if (Ctrl)
  498.     {
  499.       CloseCtrlWindow();
  500.       CtrlProc->pr_WindowPtr=OldWindowPtr;
  501.     }
  502.     if (BBSGlobal->ScreenInfo.UsePubScreen)
  503.     {
  504.       UnlockPubScreen(NULL,BBSGlobal->ScreenInfo.Scr);
  505.     }
  506.     else
  507.     {
  508.       CloseScreen(BBSGlobal->ScreenInfo.Scr);
  509.     }
  510.     BBSGlobal->ScreenInfo.Scr=NULL;
  511.   }
  512. }
  513.  
  514. BOOL OpenTheScreen( void )
  515. {
  516.   BOOL Cancel=FALSE;
  517.  
  518.   Ctrl=NULL;
  519.   CfgOpen=FALSE;
  520.  
  521.   do
  522.   {
  523.     if (BBSGlobal->ScreenInfo.UsePubScreen)
  524.     {
  525.       if (!(BBSGlobal->ScreenInfo.Scr=LockPubScreen(BBSGlobal->ScreenInfo.PubScreenName)))
  526.       {
  527.         HBBS_DoErrorMessage(EMSG_CANTLOCKPUBSCREEN,0,NULL);
  528.       }
  529.     }
  530.     if (BBSGlobal->ScreenInfo.Scr==NULL)
  531.     {
  532.       if (BBSGlobal->ScreenInfo.Scr= OpenCtrlScrn())
  533.       {
  534.         PubScreenStatus(BBSGlobal->ScreenInfo.Scr,0);
  535.       }
  536.     }
  537.     if (BBSGlobal->ScreenInfo.Scr)
  538.     {
  539.       if (OpenCtrlWindow(BBSGlobal->ScreenInfo.Scr)==0)
  540.       {
  541.         // bring screen to front..
  542.         if (!BBSGlobal->HideScreen) ScreenToFront(BBSGlobal->ScreenInfo.Scr);
  543.         OldWindowPtr=CtrlProc->pr_WindowPtr;
  544.         CtrlProc->pr_WindowPtr=Ctrl;
  545.         offx = Ctrl->BorderLeft;
  546.         offy = Ctrl->BorderTop;
  547.         updategadgets();
  548.  
  549.         HBBS_AppendStrToFile("ENV:HBBS_ScreenName", BBSGlobal->ScreenInfo.PubScreenName);
  550.  
  551.         return(TRUE);
  552.       }
  553.       else HBBS_DoErrorMessage(EMSG_NOWINDOW,0,NULL);
  554.     }
  555.     else HBBS_DoErrorMessage(EMSG_NOSCREEN,0,NULL);
  556.     if (BBSGlobal->ScreenInfo.Scr==NULL)
  557.     {
  558.       Cancel=!PickScreen();
  559.       CopyMem(&NewScr,&BBSGlobal->ScreenInfo,sizeof(struct ScreenInfoData));
  560.     }
  561.   } while (Cancel==FALSE);
  562.  
  563.   CloseTheScreen();
  564.   return(FALSE);
  565. }
  566.  
  567. BOOL ChangeScreenMode( void ) // returns FALSE if can't open new screen
  568. {
  569.   if (AllNodesShut())
  570.   {
  571.     if (PickScreen())
  572.     {
  573.       CloseTheScreen();
  574.       CopyMem(&NewScr,&BBSGlobal->ScreenInfo,sizeof(struct ScreenInfoData));
  575.       if (!OpenTheScreen())
  576.       {
  577.         HBBS_DoErrorMessage(EMSG_NOSCREENQUIT,0,NULL);
  578.         return(FALSE);
  579.       }
  580.     }
  581.   }
  582.   else HBBS_DoErrorMessage(EMSG_CANTCHANGESCREEN,0,NULL);
  583.   return(TRUE);
  584. }
  585.  
  586.  
  587. void UpdateCtrlStatus(V_BIGNUM Flags,V_BIGNUM Value)
  588. {
  589.   switch (Flags)
  590.   {
  591.     case UPD_NODESTATUS:
  592.       switch (Value)
  593.       {
  594.         case STAT_CLOSED:
  595.           strcpy(StatusText,str_STAT_CLOSED);
  596.           break;
  597.         case STAT_LOADING:
  598.           strcpy(StatusText,str_STAT_LOADING);
  599.           break;
  600.         case STAT_INITIALIZING:
  601.           strcpy(StatusText,str_STAT_INITIALIZING);
  602.           break;
  603.         case STAT_READY:
  604.           strcpy(StatusText,str_STAT_READY);
  605.           break;
  606.         case STAT_ONLINE:
  607.           strcpy(StatusText,str_STAT_ONLINE);
  608.           break;
  609.         case STAT_CLOSING:
  610.           strcpy(StatusText,str_STAT_CLOSING);
  611.           break;
  612.         default:
  613.           StatusText[0]=0;
  614.           break;
  615.       }
  616.       break;
  617.   }
  618.  
  619.   GT_SetGadgetAttrs(CtrlGadgets[Ctrl_StatusText],Ctrl,NULL,GTTX_Text,StatusText,TAG_DONE);
  620.  
  621.  
  622. /*
  623.   SetAPen(Ctrl->RPort,0); // grey
  624.   RectFill( Ctrl->RPort, 64+1+offx,79+offy,offx+628,79+offy+9);
  625.   SetAPen(Ctrl->RPort,1); // black!
  626.   SetBPen(Ctrl->RPort,0); // grey!
  627.   Move( Ctrl->RPort,64+1+offx,8+78+offy);
  628.   Text( Ctrl->RPort,str,strlen(str));
  629. */
  630. }
  631.  
  632.  
  633. void ClearBBSGlobalData(struct BBSGlobalData *BG )
  634. {
  635.   BG->BBSName=NULL;
  636.   BG->BBSSerial=0;
  637.   BG->BBSLocation=NULL;
  638.   BG->BBSCountry=NULL;
  639.   BG->BBSGroup=NULL;
  640.   BG->BBSNodes=0;
  641.   BG->SysopAccount=NULL;
  642.   BG->Drive=NULL;
  643.   BG->BBSDrive=NULL;
  644.   BG->MinFreeSpace=NULL;
  645.   BG->NoFreeSpaceScript=NULL;
  646.   BG->ButtonName=NULL;
  647.   BG->ButtonCMD=NULL;
  648.   BG->HideScreen=FALSE;
  649.   BG->ErrorLogFile=NULL;
  650.   BG->ScreenInfo.ScrModeID=0;
  651.   BG->ScreenInfo.ScrHeight=0;
  652.   BG->ScreenInfo.ScrWidth=0;
  653.   BG->ScreenInfo.ScrDepth=0;
  654.   BG->ScreenInfo.PubScreenName=NULL;
  655.   BG->ScreenInfo.UsePubScreen=FALSE;
  656.   BG->UserDataFileName=NULL;
  657. //  BG->NewUserAccessLevel=0;
  658.   BG->MaxUsernameAttempts=0;
  659.   BG->MaxPasswordAttempts=0;
  660.   BG->MinPasswordLength=0;
  661.   BG->Languages=0;
  662.   BG->EditorCMD=NULL;
  663.   BG->LastCalledDate[0]=0;
  664.   BG->LastCalledTime[0]=0;
  665.   BG->CallsToday=0;
  666. }
  667.  
  668. void SetBBSGlobalDefaults(struct BBSGlobalData *BG )
  669. {
  670.   BG->BBSSerial=0;
  671.   FreeAndSet(&BG->BBSLocation,"UnKnown");
  672.   FreeAndSet(&BG->BBSCountry,"UnKnown");
  673.   FreeAndSet(&BG->SysopAccount,"Sysop");
  674.   BG->MinFreeSpace=4096;
  675.   FreeAndSet(&BG->ErrorLogFile,FILE_ERRORLOG);
  676.   BG->ScreenInfo.ScrModeID=167936; // pal hi-res screen..
  677.   BG->ScreenInfo.ScrHeight=256;
  678.   BG->ScreenInfo.ScrWidth=640;
  679.   BG->ScreenInfo.ScrDepth=2;
  680.   FreeAndSet(&BG->ScreenInfo.PubScreenName,str_CtrlScrnName);
  681.   BG->ScreenInfo.UsePubScreen=FALSE;
  682.   BG->CopyBufferSize=32768; // 32K
  683.  
  684.   FreeAndSet(&BG->UserDataFileName,"HBBS:System/Data/User.Data");
  685. //  BG->NewUserAccessLevel=0;
  686.   BG->MaxUsernameAttempts=3;
  687.   BG->MaxPasswordAttempts=3;
  688.   BG->MinPasswordLength=4;
  689. }
  690.  
  691. void FreeBBSGlobalData(struct BBSGlobalData *BG)
  692. {
  693.   FreeStr(BG->BBSName);
  694.   FreeStr(BG->BBSLocation);
  695.   FreeStr(BG->BBSCountry);
  696.   FreeStr(BG->SysopAccount);
  697.   FreeStr(BG->BBSDrive);
  698.   FreeStr(BG->NoFreeSpaceScript);
  699.   FreeStr(BG->ErrorLogFile);
  700.   FreeStr(BG->UserDataFileName);
  701.   FreeStr(BG->EditorCMD);
  702.   FreeStr(BG->ScreenInfo.PubScreenName);
  703.   FreeStrList(BG->BBSGroup);
  704.   FreeStrList(BG->Drive);
  705.   FreeStrList(BG->ButtonName);
  706.   FreeStrList(BG->ButtonCMD);
  707.   FreeStrList(BG->LanguageName);
  708.   FreeStrList(BG->LanguageExtn);
  709. }
  710.  
  711. V_ERROR LoadBBSGlobalData(char *filename,struct BBSGlobalData *BG )
  712. {
  713.   struct CfgFileData *BBSCFG;
  714.   V_ERROR error=TYPE_NONE;
  715.  
  716.   ClearBBSGlobalData(BG);
  717.   SetBBSGlobalDefaults(BG);
  718.   if (BBSCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  719.   {
  720.     // get settings!
  721.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSNodes,VTYPE_BIGNUM,OPT_BBS_BBSNodes,OPT_SINGLE);
  722.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSName,VTYPE_STRING,OPT_BBS_BBSName,OPT_SINGLE);
  723.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSSerial,VTYPE_BIGNUM,OPT_BBS_BBSSerial,OPT_SINGLE);
  724.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSLocation,VTYPE_STRING,OPT_BBS_BBSLocation,OPT_SINGLE);
  725.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSCountry,VTYPE_STRING,OPT_BBS_BBSCountry,OPT_SINGLE);
  726.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSGroup,VTYPE_STRINGLIST,OPT_BBS_BBSGroup,OPT_MULTI);
  727.     HBBS_GetSetting(BBSCFG,(void *)&BG->SysopAccount,VTYPE_STRING,OPT_BBS_SysopAccount,OPT_SINGLE);
  728.     HBBS_GetSetting(BBSCFG,(void *)&BG->Drive,VTYPE_STRINGLIST,OPT_BBS_Drive,OPT_MULTI);
  729.     HBBS_GetSetting(BBSCFG,(void *)&BG->BBSDrive,VTYPE_STRING,OPT_BBS_BBSDrive,OPT_SINGLE);
  730.     HBBS_GetSetting(BBSCFG,(void *)&BG->MinFreeSpace,VTYPE_BIGNUM,OPT_BBS_MinFreeSpace,OPT_SINGLE);
  731.     HBBS_GetSetting(BBSCFG,(void *)&BG->NoFreeSpaceScript,VTYPE_STRING,OPT_BBS_NoFreeSpaceScript,OPT_SINGLE);
  732.     HBBS_GetSetting(BBSCFG,(void *)&BG->ButtonName,VTYPE_STRINGLIST,OPT_BBS_ButtonName,OPT_MULTI);
  733.     HBBS_GetSetting(BBSCFG,(void *)&BG->ButtonCMD,VTYPE_STRINGLIST,OPT_BBS_ButtonCMD,OPT_MULTI);
  734.     HBBS_GetSetting(BBSCFG,(void *)&BG->HideScreen,VTYPE_BOOL,OPT_BBS_HideScreen,OPT_SINGLE);
  735.     HBBS_GetSetting(BBSCFG,(void *)&BG->ErrorLogFile,VTYPE_STRING,OPT_BBS_ErrorLogFile,OPT_SINGLE);
  736. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScreenInfo.ScrModeID,VTYPE_BIGNUM,OPT_BBS_ScrModeID,OPT_SINGLE);
  737. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScreenInfo.ScrHeight,VTYPE_BIGNUM,OPT_BBS_ScrHeight,OPT_SINGLE);
  738. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScreenInfo.ScrWidth,VTYPE_BIGNUM,OPT_BBS_ScrWidth,OPT_SINGLE);
  739. //    HBBS_GetSetting(BBSCFG,(void *)&BG->ScreenInfo.ScrDepth,VTYPE_BIGNUM,OPT_BBS_ScrDepth,OPT_SINGLE);
  740.     HBBS_GetSetting(BBSCFG,(void *)&BG->UserDataFileName,VTYPE_STRING,OPT_BBS_UserDataFileName,OPT_SINGLE);
  741. //    HBBS_GetSetting(BBSCFG,(void *)&BG->NewUserAccessLevel,VTYPE_SMALLNUM,OPT_BBS_NewUserAccessLevel,OPT_SINGLE);
  742.     HBBS_GetSetting(BBSCFG,(void *)&BG->MaxUsernameAttempts,VTYPE_SMALLNUM,OPT_BBS_MaxUsernameAttempts,OPT_SINGLE);
  743.     HBBS_GetSetting(BBSCFG,(void *)&BG->MaxPasswordAttempts,VTYPE_SMALLNUM,OPT_BBS_MaxPasswordAttempts,OPT_SINGLE);
  744.     HBBS_GetSetting(BBSCFG,(void *)&BG->MinPasswordLength,VTYPE_SMALLNUM,OPT_BBS_MinPasswordLength,OPT_SINGLE);
  745.     HBBS_GetSetting(BBSCFG,(void *)&BG->LanguageName,VTYPE_STRINGLIST,OPT_BBS_LanguageName,OPT_MULTI);
  746.     BG->Languages=HBBS_GetSetting(BBSCFG,(void *)&BG->LanguageExtn,VTYPE_STRINGLIST,OPT_BBS_LanguageExtn,OPT_MULTI);
  747.     HBBS_GetSetting(BBSCFG,(void *)&BG->EditorCMD,VTYPE_STRING,OPT_BBS_EditorCMD,OPT_SINGLE);
  748.     HBBS_GetSetting(BBSCFG,(void *)&BG->CopyBufferSize,VTYPE_BIGNUM,OPT_BBS_CopyBufferSize,OPT_SINGLE);
  749.  
  750.  
  751.     HBBS_FlushConfig(BBSCFG);
  752.   }
  753.   return(error);
  754. }
  755.  
  756. static VOID cleanup(ULONG num)
  757. {
  758.   CloseLoadingWindow();
  759.  
  760.   if (num)
  761.   {
  762.     if (HBBSCommonBase) HBBS_DoErrorMessage(num,0,NULL);
  763.   }
  764.  
  765.   FreeImages();
  766.  
  767.   CloseFont( HBBSFont ) ;
  768.   CloseLibs();
  769.  
  770.   if (HBBSCommonBase)
  771.   {
  772.     HBBS_CleanUpCommon();
  773.     CloseLibrary (HBBSCommonBase);
  774.   }
  775.  
  776.   if (BBSGlobal)
  777.   {
  778.     if (BBSGlobal->CtrlMainPort) DeletePort(BBSGlobal->CtrlMainPort);
  779.     if (BBSGlobal->CtrlMainReplyPort) DeletePort(BBSGlobal->CtrlMainReplyPort);
  780.     if (BBSGlobal->NodeGlobalData) FreeVec(BBSGlobal->NodeGlobalData);
  781.     FreeVec(BBSGlobal);
  782.   }
  783.  
  784.   if (ReqToolsBase)
  785.     CloseLibrary ((struct Library *)ReqToolsBase);
  786.  
  787.   exit(0);
  788. }
  789.  
  790. int OpenTheDiskFonts( void )
  791. {
  792.   int OKSoFar = 1;
  793. if ((HBBSFont = OpenDiskFont( &HBBS8066 )) == NULL )
  794.   OKSoFar = 0;
  795. return ( OKSoFar );
  796. }
  797.  
  798.  
  799. void init(VOID) // will never return anything as if something in here fails the
  800. {               // program is terminated
  801.  
  802.   struct MsgPort *tmpport;
  803.  
  804.   if (OpenLibs())
  805.   {
  806.     cleanup(EMSG_NOLIBS);
  807.   }
  808.   else
  809.   {
  810.     if (!OpenTheDiskFonts())
  811.     {
  812.       cleanup(EMSG_NOFONT);
  813.     }
  814.     else
  815.     {
  816.       if (!MakeImages())
  817.       {
  818.         if (!(ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
  819.         {
  820.           cleanup(EMSG_NOREQTOOLS);
  821.         }
  822.  
  823.         if(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0))
  824.         {
  825.           if (HBBS_InitCommon())
  826.           {
  827.  
  828.  
  829.             Forbid();
  830.             tmpport=FindPort(CtrlMainPortName);
  831.             Permit();
  832.  
  833.             if (tmpport)
  834.               cleanup(EMSG_ALREADYSTARTED);
  835.  
  836.             if (BBSGlobal=(struct BBSGlobalData*) AllocVec(sizeof(struct BBSGlobalData),MEMF_PUBLIC|MEMF_CLEAR))
  837.             {
  838.               if (BBSGlobal->NodeGlobalData=(struct NodeData*) AllocVec(sizeof(struct NodeData),MEMF_PUBLIC|MEMF_CLEAR))
  839.               {
  840.                 if (BBSGlobal->CtrlMainPort=CreatePort(CtrlMainPortName,0))
  841.                 {
  842.                   if (BBSGlobal->CtrlMainReplyPort=CreatePort(0,0))
  843.                   {
  844.                     NewScr.UsePubScreen=FALSE;
  845.                     NewScr.PubScreenName=DupStr(str_CtrlScrnName);
  846.                     HBBS_SetBBS(BBSGlobal);
  847.                     return;
  848.                   }
  849.                 }
  850.               }
  851.             }
  852.           }
  853.         }
  854.       }
  855.       cleanup(EMSG_NOMEM);
  856.     }
  857.   }
  858. }
  859.  
  860. void RequestNode(struct NodeData *ND,V_BIGNUM status)
  861. {
  862.   struct StatusMsg *SMsg;
  863.  
  864.   // memory will be free'd by NODE program (if node is alive of course!)
  865.   if (SMsg=(struct StatusMsg *)AllocVec(sizeof(struct StatusMsg),MEMF_PUBLIC))
  866.   {
  867.     SMsg->message.mn_Node.ln_Type = NT_MESSAGE;
  868.     SMsg->message.mn_ReplyPort=NULL;  // must set to null!
  869.     SMsg->message.mn_Length=sizeof(struct StatusMsg);
  870.     SMsg->MsgType=mtype_STATUS;
  871.     SMsg->Status=status;
  872.     SendMessage((struct Message*)SMsg,ND->PortName);
  873.   }
  874. }
  875.  
  876. // Main Routine to close down a node.
  877.  
  878. void StopNode(short nodenum)
  879. {
  880.   struct NodeData *nd;
  881.  
  882.   if (nd=HBBS_NodeDataPtr(nodenum))
  883.   {
  884.     RequestNode(nd,STAT_REQUESTCLOSE);
  885.   }
  886. }
  887.  
  888. void StartNode(short nodenum)
  889. {
  890.   struct NodeData *nd;
  891.   static ULONG sysargs[] =
  892.   {
  893.     SYS_Input,NULL,
  894.     SYS_Output,NULL,
  895.     SYS_Asynch,TRUE,
  896.     SYS_UserShell,TRUE,
  897.     NP_Priority,0L,
  898.     TAG_DONE
  899.   };
  900.   BPTR outputfile;
  901.   BOOL ok=FALSE;
  902.   char command[100]; // *C* Change me!!! :-)
  903.  
  904.   if (nd=HBBS_NodeDataPtr(nodenum))
  905.   {
  906.     if (nd->Status==STAT_CLOSED) // check to see if node is already open first.
  907.     {
  908.       nd->Status=STAT_LOADING;
  909.       UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  910.  
  911. #ifndef DEBUGNODE
  912.       if (outputfile = Open(str_CONSOLE,MODE_OLDFILE))
  913.       {
  914.         sysargs[1]=(ULONG)outputfile;
  915.         sprintf(command,"HBBS:Doors/System/Node %d",nodenum);
  916.  
  917.         if (SystemTagList(command,(struct TagItem *)sysargs)==0)
  918.         {
  919.           ok=TRUE;
  920.         }
  921.       }
  922.       if (!ok)
  923.       {
  924.         nd->Status=STAT_CLOSED;
  925.         HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,"Error Starting Node!",TYPE_CRITICAL);
  926.       }
  927. #else
  928.       rtEZRequest("Start Node Program NOW!","OK!",NULL,NULL,NULL);
  929. #endif
  930.     }
  931.   }
  932. }
  933.  
  934. // only called once, this just starts all the nodes that have autostart enabled!
  935.  
  936. void StartNodes( void )
  937. {
  938.   struct NodeData *nd;
  939.  
  940.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  941.   {
  942.     if (nd->AutoStart) StartNode(nd->NodeNum);
  943.   }
  944. }
  945.  
  946. void StopAllNodes( void )
  947. {
  948.   struct NodeData *nd;
  949.  
  950.   for (nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd = (struct NodeData*)nd->node.ln_Succ)
  951.   {
  952.     // if node is not busy then tell it to shutdown..
  953.     if (nd->Status==STAT_READY) StopNode(nd->NodeNum);
  954.   }
  955. }
  956.  
  957. void HandleStatusMsg( struct StatusMsg *SMsg )
  958. {
  959.   struct NodeData *nd;
  960.  
  961.   if (nd=HBBS_NodeDataPtr(SMsg->NodeNum))
  962.   {
  963.     GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,nd->NodeNum,TAG_DONE);
  964. #ifdef KS20
  965.     LastNodeClicked=SMsg->NodeNum;
  966. #endif
  967.     // get the nodestatus node and set the status variable
  968.     // actually the NODE program could do this but the control program would not be
  969.     // aware, so we send a msg.. :-)
  970.  
  971.     nd->Status=SMsg->Status;
  972.  
  973.     UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  974.  
  975.     if (nd->Status==STAT_CLOSED)
  976.     {
  977.       StopNode(SMsg->NodeNum);
  978.       GT_SetGadgetAttrs(CtrlGadgets[Ctrl_LV1],Ctrl,NULL,GTLV_Labels,NULL,TAG_DONE);
  979.     }
  980.   }
  981.   // reply wanted ??
  982.   if (SMsg->message.mn_ReplyPort)
  983.   {
  984.     // yup, reply it then..
  985.     ReplyMsg((struct Message *)SMsg);
  986.   }
  987.   else
  988.   {
  989.     // nope, free the mem..
  990.     FreeVec(SMsg);
  991.   }
  992. }
  993.  
  994. //void HandleAskMsg(struct AskMsg *AMsg)
  995. //{
  996. //  switch (AMsg->Flags)
  997. //  {
  998. //    case ASK_BBSGLOBAL:
  999. //      AMsg->Pointer=(void *)BBSGlobal;
  1000. //      break;
  1001. //    default:
  1002. //      puts("UnKnown AskMsg Received!");
  1003. //      break;
  1004. //  }
  1005. //  ReplyMsg((struct Message *)AMsg);
  1006. //}
  1007.  
  1008. void HandleRequestMsg(struct RequestMsg *RMsg)
  1009. {
  1010.   switch (RMsg->Flags)
  1011.   {
  1012.     case REQ_UPDATEINFO:
  1013.       UpdateInfoLists();
  1014.       break;
  1015.     default:
  1016.       puts("UnKnown RequestMsg Received!");
  1017.       break;
  1018.   }
  1019.   ReplyMsg((struct Message *)RMsg);
  1020. }
  1021.  
  1022. // the message handler!
  1023.  
  1024. void HandleMsg(void )
  1025. {
  1026.   struct NodeMsg *Msg;
  1027.  
  1028.   while (Msg=(struct NodeMsg *)GetMsg(BBSGlobal->CtrlMainPort))
  1029.   {
  1030.     switch (Msg->MsgType)
  1031.     {
  1032. //      case mtype_ASK:
  1033. //        HandleAskMsg((struct AskMsg *)Msg);
  1034. //        break;
  1035.       case mtype_STATUS:
  1036.         HandleStatusMsg((struct StatusMsg *)Msg);
  1037.         break;
  1038.       case mtype_REQUEST:
  1039.         HandleRequestMsg((struct RequestMsg *)Msg);
  1040.         break;
  1041.       default:
  1042.         puts("UnKnown Message Type!");
  1043.         break;
  1044.     }
  1045.   }
  1046. }
  1047.  
  1048. BOOL CheckDoubleClick(WORD MouseX,WORD MouseY,LONG sec,LONG mic)
  1049. {
  1050.   if (DoubleClick(last_sec,last_mic,sec,mic) && (MouseX==last_x && MouseY==last_y))
  1051.   {
  1052.     // clear values so we can doubleclick and doubleclick again without it recognising 3 clicks as being 2 doubleclicks..
  1053.     last_x=0;
  1054.     last_y=0;
  1055.     last_sec=0;
  1056.     last_mic=0;
  1057.     return(TRUE);
  1058.   }
  1059.   last_x=MouseX;
  1060.   last_y=MouseY;
  1061.   last_sec=sec;
  1062.   last_mic=mic;
  1063.   return(FALSE);
  1064. }
  1065.  
  1066. /* Menu Processing for CtrlMenu */
  1067. /* Just pass the code field from an IDCMP_MENUPICK or IDCMP_MENUHELP message. */
  1068.  
  1069. short ProcessMenuIDCMPCtrlMenu( UWORD MenuNumber)
  1070. {
  1071.   UWORD MenuNum;
  1072.   UWORD ItemNumber;
  1073.   UWORD SubNumber;
  1074.   short Done=0;           /* Set Done to 1 to forget rest of next selects. */
  1075.   short Quit=0;
  1076.   struct MenuItem *item;
  1077.  
  1078.   while ((MenuNumber != MENUNULL) && (Done == 0))
  1079.   {
  1080.     item = ItemAddress( CtrlMenu, MenuNumber);
  1081.     MenuNum = MENUNUM(MenuNumber);
  1082.     ItemNumber = ITEMNUM(MenuNumber);
  1083.     SubNumber = SUBNUM(MenuNumber);
  1084.     switch ( MenuNum )
  1085.     {
  1086.       case NOMENU :
  1087.         /* No Menu Selected. */
  1088.         break;
  1089.       case Menu_1 :
  1090.         switch ( ItemNumber )
  1091.         {
  1092.           case NOITEM :
  1093.             /* No Item selcted. */
  1094.             break;
  1095.           case CtrlMenu_About :
  1096.             /* Item Text : About */
  1097.             About();
  1098.             break;
  1099.           case CtrlMenu_ScreenMode :
  1100.             /* Item Text : Screen Mode */
  1101.             Done=1;
  1102.             if (ChangeScreenMode()==FALSE) Quit=1;
  1103.             break;
  1104.           case bar :
  1105.             /* Item Text : bar */
  1106.             break;
  1107.           case CtrlMenu_Qui :
  1108.             /* Item Text : Quit! */
  1109.             StopAllNodes();
  1110.             if (AllNodesShut()) Quit=1;
  1111.             Done=1;
  1112.             break;
  1113.         }
  1114.         break;
  1115.     }
  1116.     if (!Done) MenuNumber = item->NextSelect;
  1117.   }
  1118.   return(Quit);
  1119. }
  1120.  
  1121. short ProcessWindowCtrl( LONG Class, UWORD Code, APTR IAddress, WORD MouseX, WORD MouseY, LONG Seconds, LONG Micros)
  1122. {
  1123.   #ifdef KS30
  1124.     LONG num;
  1125.   #endif
  1126.  
  1127.   char tmpstr[1024],filename[1024];
  1128.   struct NodeData *tempnode;
  1129.   struct Gadget *gad;
  1130.   struct NodeData *nd;
  1131.   short done=0;
  1132.   switch ( Class )
  1133.   {
  1134.     case IDCMP_MENUPICK:
  1135.       done=ProcessMenuIDCMPCtrlMenu(Code);
  1136.       break;
  1137.     case IDCMP_GADGETUP :
  1138.       /* Gadget message, gadget = gad. */
  1139.       gad = (struct Gadget *)IAddress;
  1140.       switch ( gad->GadgetID )
  1141.       {
  1142.         case Ctrl_LV1 :
  1143.           /* ListView pressed, Text of gadget :  */
  1144.           break;
  1145.         case Ctrl_LV1_Cycle :
  1146.           /* Cycle changed   , Text of gadget :  */ // *C* won't work if KS30 is defined..
  1147.           LastCycleClicked=Code;
  1148.           UpdateInfoLists();
  1149.  
  1150.           break;
  1151.         case Ctrl_LV1_Info :
  1152.           /* Button pressed  , Text of gadget : Information */
  1153.           break;
  1154.         case Ctrl_LV2_Nodes :
  1155.           /* ListView pressed, Text of gadget :  */
  1156.           if (Code>=0)
  1157.           {
  1158. #ifdef KS20
  1159.             LastNodeClicked=Code; // cos 2.04 is lAmE
  1160. #endif
  1161.             if (nd=HBBS_NodeDataPtr(Code)) // code contains number of listview selected
  1162.             {
  1163.               UpdateCtrlStatus(UPD_NODESTATUS,nd->Status);
  1164.               UpdateInfoLists();
  1165.  
  1166.               // right, if it's been double clicked then open the node if it's
  1167.               // currenty closed, if it's open then open it's screen..
  1168.  
  1169.               if (CheckDoubleClick(MouseX,MouseY,Seconds,Micros))
  1170.               {
  1171.                 switch(nd->Status)
  1172.                 {
  1173.                   case STAT_CLOSED:
  1174.                     StartNode(nd->NodeNum);
  1175.                     break;
  1176.                   case STAT_READY:
  1177.                   case STAT_ONLINE:
  1178.                     RequestNode(nd,STAT_OPENSCREEN);
  1179.                     break;
  1180.                 }
  1181.               }
  1182.             }
  1183.           }
  1184.           break;
  1185.         case Ctrl_Window :
  1186.           /* Button pressed  , Text of gadget : Callers */
  1187. #ifdef KS30
  1188.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1189.           {
  1190.             if (num>=0)
  1191.             {
  1192.               if (nd=HBBS_NodeDataPtr(num))
  1193.               {
  1194.                 if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1195.                 {
  1196.                   if (nd->NodeSettings.Iconified) RequestNode(nd,STAT_OPENWINDOW); else RequestNode(nd,STAT_CLOSEWINDOW);
  1197.                 }
  1198.               }
  1199.             }
  1200.           }
  1201. #else
  1202.           if (nd=HBBS_NodeDataPtr(LastNodeClicked))
  1203.           {
  1204.             if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1205.             {
  1206.               if (nd->NodeSettings.Iconified) RequestNode(nd,STAT_OPENWINDOW); else RequestNode(nd,STAT_CLOSEWINDOW);
  1207.             }
  1208.           }
  1209. #endif
  1210.           break;
  1211.         case Ctrl_Screen :
  1212.           /* Button pressed  , Text of gadget : Screen */
  1213. #ifdef KS30
  1214.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1215.           {
  1216.             if (num>=0)
  1217.             {
  1218.               if (nd=HBBS_NodeDataPtr(num))
  1219.               {
  1220.                 if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1221.                 {
  1222.                   if (nd->ConOK==FALSE) RequestNode(nd,STAT_OPENSCREEN); else RequestNode(nd,STAT_CLOSESCREEN);
  1223.                 }
  1224.               }
  1225.             }
  1226.           }
  1227. #else
  1228.           if (nd=HBBS_NodeDataPtr(LastNodeClicked))
  1229.           {
  1230.             if ( nd->Status==STAT_READY || nd->Status==STAT_ONLINE )
  1231.             {
  1232.               if (nd->ConOK==FALSE) RequestNode(nd,STAT_OPENSCREEN); else RequestNode(nd,STAT_CLOSESCREEN);
  1233.             }
  1234.           }
  1235. #endif
  1236.           break;
  1237.         case Ctrl_Stop :
  1238.           /* Button pressed  , Text of gadget : Stop */
  1239. #ifdef KS30
  1240.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1241.           {
  1242.             if (num>=0)
  1243.             {
  1244.               StopNode(num);
  1245.             }
  1246.           }
  1247. #else
  1248.           StopNode(LastNodeClicked);
  1249. #endif
  1250.           break;
  1251.         case Ctrl_Start :
  1252.           /* Button pressed  , Text of gadget : Start */
  1253. #ifdef KS30
  1254.           if (1==GT_GetGadgetAttrs(CtrlGadgets[Ctrl_LV2_Nodes],Ctrl,NULL,GTLV_Selected,&num,TAG_DONE))
  1255.           {
  1256.             if (num>=0)
  1257.             {
  1258.               StartNode(num);
  1259.             }
  1260.           }
  1261. #else
  1262.           StartNode(LastNodeClicked);
  1263. #endif
  1264.           break;
  1265.         case Ctrl_Config : // node config..
  1266.           /* Button pressed  , Text of gadget : Config */
  1267.  
  1268.           tempnode=HBBS_NodeDataPtr(LastNodeClicked);
  1269.           sprintf(filename,"%sNodeLocal",tempnode->NodeLocation);
  1270.           strcpy(tmpstr,BBSGlobal->EditorCMD);
  1271.           replace(tmpstr,tmpstr,"{FILE}",filename);
  1272.           HBBS_RunDOSCMD(tmpstr,TRUE);
  1273.  
  1274.           break;
  1275.         case Ctrl_Configure : // open config window..
  1276.           /* Button pressed  , Text of gadget : Configure */
  1277.           if (!CfgOpen)
  1278.           {
  1279.             if (OpenCtrlCfgWindow(BBSGlobal->ScreenInfo.Scr)==0)
  1280.             {
  1281.               CfgOpen=TRUE;
  1282.             }
  1283.           }
  1284.           else
  1285.           {
  1286.             WindowToFront(CtrlCfg);
  1287.           }
  1288.           break;
  1289.         case Ctrl_Shutdown :
  1290.           /* Button pressed  , Text of gadget : Shutdown All */
  1291.           StopAllNodes();
  1292.           break;
  1293.         case Ctrl_LV3_Commands :
  1294.           if (CheckDoubleClick(MouseX,MouseY,Seconds,Micros))
  1295.           {
  1296.             strcpy(tmpstr,HBBS_ListName(BBSGlobal->ButtonCMD,Code));
  1297.             if ((tmpstr[0]) && (stricmp(tmpstr,"SEPERATOR")!=0))
  1298.             {
  1299.               HBBS_RunDOSCMD(tmpstr,TRUE);
  1300.             }
  1301.             // HandleButtonCMD(Code);
  1302.           }
  1303.           break;
  1304.       }
  1305.       break;
  1306.     case IDCMP_CLOSEWINDOW :
  1307.       /* CloseWindow Now */
  1308.       // Stop All The Nodes..
  1309.       StopAllNodes();
  1310.       if (AllNodesShut()) done=1;
  1311.       break;
  1312.     case IDCMP_REFRESHWINDOW :
  1313.       GT_BeginRefresh( Ctrl);
  1314.       /* Refresh window. */
  1315.       RendWindowCtrl( Ctrl, CtrlVisualInfo );
  1316.       GT_EndRefresh( Ctrl, TRUE);
  1317.       GT_RefreshWindow( Ctrl, NULL);
  1318.       RefreshGList( CtrlGList, Ctrl, NULL, ~0);
  1319.       break;
  1320.     case IDCMP_VANILLAKEY :
  1321.       printf("V %d %c\n",Code,Code);
  1322.       break;
  1323.     case IDCMP_RAWKEY :
  1324.       printf("R %d %c\n",Code,Code);
  1325.       break;
  1326.   }
  1327.   return(done);
  1328. }
  1329.  
  1330. BOOL ProcessWindowCtrlCfg( LONG Class, UWORD Code, APTR IAddress )
  1331. {
  1332. struct Gadget *gad;
  1333. char tmpstr[1024];
  1334. BOOL quit=FALSE;
  1335. switch ( Class )
  1336.   {
  1337.   case IDCMP_GADGETUP :
  1338.     /* Gadget message, gadget = gad. */
  1339.     gad = (struct Gadget *)IAddress;
  1340.     switch ( gad->GadgetID )
  1341.       {
  1342.       case CtrlCfg_ScreenMode :
  1343.         /* Button pressed  , Text of gadget : Pick Mode */
  1344.         quit=!ChangeScreenMode();
  1345.         break;
  1346.       case CtrlCfg_EditBBSConfig :
  1347.         strcpy(tmpstr,BBSGlobal->EditorCMD);
  1348.         replace(tmpstr,tmpstr,"{FILE}","HBBS:BBSGlobal");
  1349.         HBBS_RunDOSCMD(tmpstr,TRUE);
  1350.         break;
  1351.       case CtrlCfg_Save :
  1352.         /* Button pressed  , Text of gadget : Save */
  1353.         SaveScreenPrefs();
  1354.         break;
  1355.       }
  1356.     break;
  1357.   case IDCMP_CLOSEWINDOW :
  1358.     /* CloseWindow Now */
  1359.     CloseCtrlCfgWindow();
  1360.     CfgOpen=FALSE;
  1361.     break;
  1362.   case IDCMP_REFRESHWINDOW :
  1363.     GT_BeginRefresh( CtrlCfg);
  1364.     /* Refresh window. */
  1365.   RendWindowCtrlCfg( CtrlCfg, CtrlCfgVisualInfo );
  1366.     GT_EndRefresh( CtrlCfg, TRUE);
  1367.   GT_RefreshWindow( CtrlCfg, NULL);
  1368.   RefreshGList( CtrlCfgGList, CtrlCfg, NULL, ~0);
  1369.     break;
  1370.   }
  1371.   return(quit);
  1372. }
  1373.  
  1374. void mainloop( void )
  1375. {
  1376.   int done=0;
  1377.   ULONG class;
  1378.   WORD mousex,mousey;
  1379.   LONG secs,mics;
  1380.   UWORD code;
  1381.   struct Gadget *pgsel;
  1382.   struct IntuiMessage *imsg;
  1383.   ULONG ReturnedSig,CfgSig;
  1384.  
  1385.   while(done==0)
  1386.   {
  1387.     CfgSig=CfgOpen ? 1L <<CtrlCfg->UserPort->mp_SigBit : 0L;
  1388.  
  1389.     ReturnedSig=Wait(1L << Ctrl->UserPort->mp_SigBit |  1L << BBSGlobal->CtrlMainPort->mp_SigBit | CfgSig);
  1390.  
  1391.     if (ReturnedSig & 1L << Ctrl->UserPort->mp_SigBit)
  1392.     {
  1393.       while (imsg=GT_GetIMsg(Ctrl->UserPort))
  1394.       {
  1395.         // Copy the bits we need..
  1396.         class=imsg->Class;
  1397.         code=imsg->Code;
  1398.         mousex=imsg->MouseX;
  1399.         mousey=imsg->MouseY;
  1400.         secs=imsg->Seconds;
  1401.         mics=imsg->Micros;
  1402.         pgsel=(struct Gadget *)imsg->IAddress; /* Only reference if it is a gadget message */
  1403.         GT_ReplyIMsg(imsg);
  1404.  
  1405.         done=ProcessWindowCtrl(class, code, pgsel,mousex,mousey,secs,mics);
  1406.       }
  1407.     }
  1408.     if ((CfgOpen) && (ReturnedSig & CfgSig))
  1409.     {
  1410.       while ((CfgOpen) && (imsg=GT_GetIMsg(CtrlCfg->UserPort)))
  1411.       {
  1412.         class=imsg->Class;
  1413.         code=imsg->Code;
  1414.         pgsel=(struct Gadget *)imsg->IAddress;
  1415.         GT_ReplyIMsg(imsg);
  1416.  
  1417.         done=ProcessWindowCtrlCfg(class, code, pgsel);
  1418.       }
  1419.     }
  1420.  
  1421.     if (ReturnedSig & 1L << BBSGlobal->CtrlMainPort->mp_SigBit)
  1422.     {
  1423.       HandleMsg();
  1424.     }
  1425.   }
  1426. }
  1427.  
  1428.  
  1429. void CtrlMain(void)
  1430. {
  1431.   if (OpenTheScreen())
  1432.   {
  1433.     StartNodes();
  1434.     CloseLoadingWindow();
  1435.     mainloop();
  1436.     CloseTheScreen();
  1437.   }
  1438. }
  1439.  
  1440. V_BOOL CreateNodeList(void)
  1441. {
  1442.   short loop;
  1443.   struct NodeData *node;
  1444.   V_BOOL retval=TRUE;
  1445.   struct CfgFileData *NodeListCFG;
  1446.   UBYTE *option;
  1447.  
  1448.   if (NodeListCFG=HBBS_LoadConfig(FILE_NODELIST,LCFG_NONE))
  1449.   {
  1450.  
  1451.     if (BBSGlobal->NodeList=HBBS_CreateList())
  1452.     {
  1453.       for (loop=0;loop<BBSGlobal->BBSNodes && retval==TRUE;loop++)
  1454.       {
  1455.         retval=FALSE;
  1456.         // note use of MEMF_CLEAR flag, this will set ALL pointers to NULL so we don't have
  1457.         // to do any more work setting up stuff like node->NodeLocation=NULL;
  1458.  
  1459.         if (node=(struct NodeData*)AllocVec(sizeof(struct NodeData),MEMF_PUBLIC|MEMF_CLEAR))
  1460.         {
  1461.           if (node->node.ln_Name=AllocVec(LEN_NODESTATNAME,MEMF_PUBLIC))
  1462.           {
  1463.             sprintf(node->node.ln_Name,"Node_%d",loop);
  1464.             sprintf(node->PortName,"HBBS_Node_%d",loop); // named for door access
  1465.             node->NodeNum=loop;
  1466.  
  1467.             if (node->DoorList=HBBS_CreateList())
  1468.             {
  1469.               if (node->TaggedFileList=HBBS_CreateList())
  1470.               {
  1471.  
  1472.                 if (node->CurrentLine=AllocVec(LEN_CURRENTLINE,MEMF_PUBLIC))
  1473.                 {
  1474.                   if (node->CurrentLineWrap=AllocVec(LEN_CURRENTLINE,MEMF_PUBLIC))
  1475.                   {
  1476.                     if (node->CharsAllowed=AllocVec(256,MEMF_CLEAR))
  1477.                     {
  1478.                       if (option=AllocVec(strlen(OPT_NODE_Location)+6+1,MEMF_PUBLIC|MEMF_CLEAR))
  1479.                       {
  1480.                         sprintf(option,"%s%d",OPT_NODE_Location,loop);
  1481.                         if (HBBS_GetSetting(NodeListCFG,(void *)&node->NodeLocation,VTYPE_PATH,option,OPT_SINGLE))
  1482.                         {
  1483.                           retval=TRUE; // temporary usage of variable..
  1484.                         } else HBBS_DoErrorMessage(EMSG_NOTENOUGHNL,0,NULL);
  1485.                         FreeVec(option);
  1486.                       }
  1487.                       if ((retval=TRUE) &&(option=AllocVec(strlen(OPT_NODE_AutoStart)+6+1,MEMF_PUBLIC|MEMF_CLEAR)))
  1488.                       {
  1489.                         retval=FALSE;// end of temportary esage..
  1490.                         sprintf(option,"%s%d",OPT_NODE_AutoStart,loop);
  1491.                         if (HBBS_GetSetting(NodeListCFG,(void *)&node->AutoStart,VTYPE_BOOL,option,OPT_SINGLE))
  1492.                         {
  1493.                           // we have to add the node to the list here because
  1494.                           // loadnodesettings will not work without it being in the list of nodes.
  1495.                           // if we fail to load the settings however, the node is removed from the list again
  1496.                           AddTail(BBSGlobal->NodeList,(struct Node*)node);
  1497.                           if (LoadNodeSettingsData(loop,&node->NodeSettings)==TYPE_NONE)
  1498.                           {
  1499.                             retval=TRUE;
  1500.                           }
  1501.                           else
  1502.                           {
  1503.  
  1504.                             Remove((struct Node*)node);
  1505.                           }
  1506.                         } else HBBS_DoErrorMessage(EMSG_NOAUTOSTART,loop,NULL);
  1507.                         FreeVec(option);
  1508.                       }
  1509.                       else retval=FALSE;
  1510.                       HBBS_ResetNodeData(node);
  1511.                     }
  1512.                   }
  1513.                 }
  1514.               }
  1515.             }
  1516.           }
  1517.         }
  1518.       }
  1519.     }
  1520.  
  1521.     HBBS_FlushConfig(NodeListCFG);
  1522.   } else retval=FALSE;
  1523.   return(retval);
  1524. }
  1525.  
  1526. void FreeNode(struct NodeData *nd)
  1527. {
  1528.   if (nd->node.ln_Name) FreeVec(nd->node.ln_Name);
  1529.   if (nd->CurrentLine) FreeVec(nd->CurrentLine);
  1530.   if (nd->CurrentLineWrap) FreeVec(nd->CurrentLineWrap);
  1531.   if (nd->CharsAllowed) FreeVec(nd->CharsAllowed);
  1532.   if (nd->NodeLocation)
  1533.   {
  1534.     FreeStr(nd->NodeLocation);
  1535.     nd->NodeLocation=NULL;
  1536.   }
  1537.  
  1538.   if (nd->DoorList)
  1539.   {
  1540.     PrintList(nd->DoorList); // *C* print them out, there is a bug if any are printed!
  1541.     FreeVec(nd->DoorList); // the list should *always* empty at this point
  1542.   }
  1543.   if (nd->TaggedFileList)
  1544.   {
  1545.     FreeVec(nd->TaggedFileList);
  1546.   }
  1547. }
  1548.  
  1549. void FreeNodeList(void)
  1550. {
  1551.   struct NodeData *nd;
  1552.   if (BBSGlobal->NodeList)
  1553.   {
  1554.     while ((nd = (struct NodeData*)BBSGlobal->NodeList->lh_Head) && (nd->node.ln_Succ))
  1555.     {
  1556.       FreeNode(nd);
  1557.       Remove((struct Node *)nd);
  1558.       FreeVec(nd);
  1559.     }
  1560.     FreeVec(BBSGlobal->NodeList);
  1561.   }
  1562. }
  1563.  
  1564. BOOL CreateConfList( void )
  1565. {
  1566.   short loop;
  1567.   struct CfgFileData *ConfListCFG,*ConfCFG;
  1568. //  UBYTE *filename;
  1569.   UBYTE filename[BIG_STR];
  1570.   struct ConfData *NewConf;
  1571.   BOOL error=FALSE;
  1572.   BOOL retval=FALSE;
  1573.   V_STRINGLIST tmplist=NULL;
  1574.   struct Node *tmpnode;
  1575.  
  1576.   BBSGlobal->ConfList=NULL; // initialise so that FreeConfList can decide wether or not to free the list..
  1577.  
  1578.   if (ConfListCFG=HBBS_LoadConfig(FILE_CONFLIST,LCFG_NONE))
  1579.   {
  1580. //    HBBS_GetSetting(ConfListCFG,(void *)&BBSGlobal->NewUserConf,VTYPE_BIGNUM,OPT_CONFL_NewUserConf,OPT_SINGLE);
  1581.     HBBS_GetSetting(ConfListCFG,(void *)&BBSGlobal->Conferences,VTYPE_BIGNUM,OPT_CONFL_Conferences,OPT_SINGLE);
  1582.     if ((BBSGlobal->Conferences==HBBS_GetSetting(ConfListCFG,(void *)&tmplist,VTYPE_PATHLIST,OPT_CONFL_ConfPath,OPT_MULTI))
  1583.        && (BBSGlobal->Conferences>0))
  1584.     {
  1585.  
  1586.       if (BBSGlobal->ConfList=HBBS_CreateList())
  1587.       {
  1588.         for (loop=0;loop<BBSGlobal->Conferences && !error ;loop++)
  1589.         {
  1590.           error=TRUE;
  1591.           if (tmpnode=GetNode(tmplist,loop))
  1592.           {
  1593.             if (NewConf=AllocVec(sizeof(struct ConfData),MEMF_PUBLIC|MEMF_CLEAR)) // WARNING: use MEMF_CLEAR here to initialise pointer to NULL
  1594.             {
  1595.  
  1596. //** Removed
  1597. //              if (filename=AllocVec(strlen(tmpnode->ln_Name)+strlen(FILENAME_CONFCONFIG)+1,MEMF_PUBLIC))
  1598. //              {
  1599. //**
  1600.               strcpy(filename,tmpnode->ln_Name);
  1601.               strcat(filename,FILENAME_CONFCONFIG);
  1602.  
  1603.               if (ConfCFG=HBBS_LoadConfig(filename,LCFG_NONE))
  1604.               {
  1605.                 NewConf->ConfPath=DupStr(tmpnode->ln_Name);
  1606.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->node.ln_Name ,VTYPE_STRING     ,OPT_CONF_ConfName      ,OPT_SINGLE);
  1607.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfActive   ,VTYPE_BOOL       ,OPT_CONF_ConfActive    ,OPT_SINGLE);
  1608.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfAccess   ,VTYPE_SMALLNUM   ,OPT_CONF_ConfAccess    ,OPT_SINGLE);
  1609.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->HoldFileList ,VTYPE_STRING     ,OPT_CONF_HoldFileList  ,OPT_SINGLE);
  1610.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->HoldFiles    ,VTYPE_PATHLIST   ,OPT_CONF_HoldFiles     ,OPT_MULTI);
  1611.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->BadFileList  ,VTYPE_STRING     ,OPT_CONF_BadFileList   ,OPT_SINGLE);
  1612.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->BadFiles     ,VTYPE_PATHLIST   ,OPT_CONF_BadFiles      ,OPT_MULTI);
  1613.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->PartUpload   ,VTYPE_PATHLIST   ,OPT_CONF_PartUpload       ,OPT_MULTI);
  1614.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->Upload       ,VTYPE_PATHLIST   ,OPT_CONF_Upload        ,OPT_MULTI);
  1615.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->Download     ,VTYPE_PATHLIST   ,OPT_CONF_Download      ,OPT_MULTI);
  1616.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->MaxDIZLines  ,VTYPE_SMALLNUM   ,OPT_CONF_MaxDIZLines   ,OPT_SINGLE);
  1617.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->MenuPrompt   ,VTYPE_STRING     ,OPT_CONF_MenuPrompt    ,OPT_SINGLE);
  1618.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->AutoMailScan ,VTYPE_BOOL       ,OPT_CONF_AutoMailScan  ,OPT_SINGLE);
  1619.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->ConfPassWD   ,VTYPE_STRING     ,OPT_CONF_ConfPassWD    ,OPT_SINGLE);
  1620.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->UserAllowed  ,VTYPE_STRINGLIST ,OPT_CONF_UserAllowed   ,OPT_MULTI);
  1621.                 HBBS_GetSetting(ConfCFG,(void *)&NewConf->KeepDIZWithFile,VTYPE_BOOL       ,OPT_CONF_KeepDIZWithFile    ,OPT_SINGLE);
  1622.                 NewConf->FileLists=HBBS_GetSetting(ConfCFG,(void *)&NewConf->FileList     ,VTYPE_STRINGLIST ,OPT_CONF_FileList      ,OPT_MULTI);
  1623.  
  1624.                 // *C* check all requires fields are present!
  1625.                 AddTail(BBSGlobal->ConfList,(struct Node*)NewConf);
  1626.                 NewConf->ConfNum=loop+1; // set the conference number
  1627.                 error=FALSE;
  1628.  
  1629.                 HBBS_FlushConfig(ConfCFG);
  1630.               }
  1631.  
  1632. //** Removed
  1633. //                FreeVec(filename);
  1634. //              }
  1635. //**
  1636.             }
  1637.           }
  1638.         }
  1639.         retval=!error; // return TRUE if NO error..
  1640.       }
  1641.     }
  1642.     FreeStrList(tmplist);
  1643.     HBBS_FlushConfig(ConfListCFG);
  1644.   }
  1645.   return(retval);
  1646. }
  1647.  
  1648. void FreeConfList( void )
  1649. {
  1650.   struct ConfData *Conf;
  1651.   if (BBSGlobal->ConfList)
  1652.   {
  1653.     while (BBSGlobal->ConfList->lh_Head->ln_Succ)
  1654.     {
  1655.       Conf=(struct ConfData*)BBSGlobal->ConfList->lh_Head;
  1656.  
  1657.       // free the data..
  1658.  
  1659.       FreeStr(Conf->node.ln_Name);
  1660.       FreeStr(Conf->HoldFileList);
  1661.       FreeStrList(Conf->HoldFiles);
  1662.       FreeStr(Conf->BadFileList);
  1663.       FreeStrList(Conf->BadFiles);
  1664.       FreeStrList(Conf->PartUpload);
  1665.       FreeStrList(Conf->FileList);
  1666.       FreeStrList(Conf->Upload);
  1667.       FreeStrList(Conf->Download);
  1668.       FreeStr(Conf->MenuPrompt);
  1669.       FreeStr(Conf->ConfPassWD);
  1670.       FreeStrList(Conf->UserAllowed);
  1671.       FreeStr(Conf->ConfPath);
  1672.       Remove((struct Node*)Conf);
  1673.       FreeVec(Conf);
  1674.     }
  1675.     FreeVec(BBSGlobal->ConfList);
  1676.   }
  1677. }
  1678.  
  1679. BOOL CheckDirs(struct List *list)
  1680. {
  1681.   struct Node *node;
  1682.   BOOL error=FALSE;
  1683.  
  1684.   // i COULD put && !error in the loop check, but it's more usefull for the sysop
  1685.   // if he/she knows about all the things that are wrong in one go..
  1686.  
  1687.   for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
  1688.   {
  1689.     if (node->ln_Name)
  1690.     {
  1691.       if (!PathOK(node->ln_Name))
  1692.       {
  1693.         error=TRUE;
  1694.         HBBS_DoErrorMessage(EMSG_PATHMISSING,0,node->ln_Name);
  1695.       }
  1696.     }
  1697.   }
  1698.   return((BOOL)!error); // return FALSE if the WAS an error..
  1699. }
  1700.  
  1701. BOOL CheckConfPaths( void )
  1702. {
  1703.   char *str;
  1704.   struct ConfData *Conf;
  1705.   short error=0;
  1706.  
  1707.   for (Conf = (struct ConfData *)BBSGlobal->ConfList->lh_Head ; Conf->node.ln_Succ && error==0 ; Conf =(struct ConfData *)Conf->node.ln_Succ)
  1708.   {
  1709.     if (str=AllocVec(strlen(Conf->ConfPath)+LEN_FILENAME_CONF_LONGEST,MEMF_PUBLIC))
  1710.     {
  1711.       error=2;
  1712.       strcpy(str,Conf->ConfPath);
  1713.       strcat(str,FILENAME_COMMANDS);
  1714.       if (PathOK(str))
  1715.       {
  1716.         strcpy(str,Conf->ConfPath);
  1717.         strcat(str,FILENAME_LOSTFILES);
  1718.         if (PathOK(str))
  1719.         {
  1720.           strcpy(str,Conf->ConfPath);
  1721.           strcat(str,FILENAME_ACCESS);
  1722.           if (PathOK(str))
  1723.           {
  1724.             strcpy(str,Conf->ConfPath);
  1725.             strcat(str,FILENAME_SCREENS);
  1726.             if (PathOK(str))
  1727.             {
  1728.               error=1;
  1729.               if (CheckDirs(Conf->HoldFiles))
  1730.               {
  1731.                 if (CheckDirs(Conf->BadFiles))
  1732.                 {
  1733.                   if (CheckDirs(Conf->PartUpload))
  1734.                   {
  1735.                     error=0;
  1736.                   }
  1737.                 }
  1738.               }
  1739.             }
  1740.           }
  1741.         }
  1742.       }
  1743.       if (error==2) HBBS_DoErrorMessage(EMSG_CONFPATHSERROR,0,NULL);
  1744.       FreeVec(str);
  1745.     }
  1746.   }
  1747.   return((BOOL)(error==0 ? TRUE : FALSE));
  1748. }
  1749.  
  1750. BOOL LoadLevels( void )
  1751. {
  1752.   struct CfgFileData *LevelListFile;
  1753.   BOOL retval=FALSE;
  1754. //  struct Node *node;
  1755.  
  1756.   BBSGlobal->AcsLevelList=NULL;
  1757.   BBSGlobal->AcsLevelNames=NULL;
  1758.   BBSGlobal->AcsLevelConfAcsDef=NULL;
  1759.  
  1760.   if (LevelListFile=HBBS_LoadConfig(FILE_ACSLEVELLIST,LCFG_NONE))
  1761.   {
  1762.     if (BBSGlobal->AcsLevels=HBBS_GetSetting(LevelListFile,(void *)&BBSGlobal->AcsLevelList,VTYPE_STRINGLIST,OPT_LLIST_LEVEL,OPT_MULTI))
  1763.     {
  1764.       if (BBSGlobal->AcsLevels==HBBS_GetSetting(LevelListFile,(void *)&BBSGlobal->AcsLevelNames,VTYPE_STRINGLIST,OPT_LLIST_LEVELNAME,OPT_MULTI))
  1765.       {
  1766.         if (BBSGlobal->AcsLevels==HBBS_GetSetting(LevelListFile,(void *)&BBSGlobal->AcsLevelConfAcsDef,VTYPE_STRINGLIST,OPT_LLIST_CONFACS,OPT_MULTI))
  1767.         {
  1768.           // we don't actually load access settings here at all, instead they are loaded for
  1769.           // each conference join and every login
  1770.           retval=TRUE;
  1771.         }
  1772.       }
  1773.     }
  1774.     HBBS_FlushConfig(LevelListFile);
  1775.   }
  1776.   else HBBS_DoErrorMessage(EMSG_LEVELSFILEERROR,0,NULL);
  1777.   return(retval);
  1778. }
  1779.  
  1780. void FreeLevels( void )
  1781. {
  1782.   if (BBSGlobal->AcsLevelList) FreeStrList(BBSGlobal->AcsLevelList);
  1783.   if (BBSGlobal->AcsLevelNames) FreeStrList(BBSGlobal->AcsLevelNames);
  1784.   if (BBSGlobal->AcsLevelConfAcsDef) FreeStrList(BBSGlobal->AcsLevelConfAcsDef);
  1785. }
  1786.  
  1787. BOOL LoadProtocols( void )
  1788. {
  1789.   struct CfgFileData *ProtocolListFile;
  1790.   struct ProtocolNode *pnode;
  1791.   BOOL error=FALSE;
  1792.   char *tmpstr=NULL;
  1793.   char optionname[BIG_STR]="Name_1";
  1794.   int num=1;
  1795.  
  1796.  
  1797.   // Load Config File..
  1798.  
  1799.   if (ProtocolListFile=HBBS_LoadConfig(FILE_PROTOCOLLIST,LCFG_NONE))
  1800.   {
  1801.     // Allocate List..
  1802.  
  1803.     if (BBSGlobal->ProtocolList=HBBS_CreateList())
  1804.     {
  1805.  
  1806.       // Find Protocol Info..
  1807.  
  1808.       while ((!error) && (HBBS_GetSetting(ProtocolListFile,(void *)&tmpstr,VTYPE_STRING,optionname,OPT_SINGLE)))
  1809.       {
  1810.         error=TRUE;
  1811.  
  1812.         // Allocate Protocol Node and get the rest of the settings..
  1813.  
  1814.         if (pnode=AllocVec(sizeof(struct ProtocolNode),MEMF_PUBLIC|MEMF_CLEAR)) // to NULL all variables!
  1815.         {
  1816.           if (pnode->node.ln_Name=DupStr(tmpstr))
  1817.           {
  1818.             FreeStr(tmpstr);
  1819.             tmpstr=NULL;
  1820.             // *C* add checking for missing items!
  1821.  
  1822.             sprintf(optionname,"Type_%d",num);
  1823.             HBBS_GetSetting(ProtocolListFile,(void *)&tmpstr,VTYPE_STRING,optionname,OPT_SINGLE);
  1824.             if (stricmp(tmpstr,"UNIDIRECTIONAL")==0) pnode->protocoltype=PTYPE_UNIDIRECTIONAL;
  1825.             if (stricmp(tmpstr,"BIDIRECTIONAL")==0) pnode->protocoltype=PTYPE_BIDIRECTIONAL;
  1826.             FreeStr(tmpstr);
  1827.             tmpstr=NULL;
  1828.  
  1829.             sprintf(optionname,"ModuleName_%d",num);
  1830.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->modulename,VTYPE_STRING,optionname,OPT_SINGLE);
  1831.  
  1832.             sprintf(optionname,"ModuleOpts_%d",num);
  1833.             if (HBBS_GetSetting(ProtocolListFile,(void *)&pnode->moduleopts,VTYPE_STRING,optionname,OPT_SINGLE)==0)
  1834.             {
  1835.               if (pnode->moduleopts=AllocVec(1,MEMF_PUBLIC))
  1836.               {
  1837.                 pnode->moduleopts[0]=0; // Null Terminated String so that string output
  1838.                                         // routines still work..
  1839.               }
  1840.             }
  1841.  
  1842.             sprintf(optionname,"AllowUL_%d",num);
  1843.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_ul,VTYPE_BOOL,optionname,OPT_SINGLE);
  1844.  
  1845.             sprintf(optionname,"AllowDL_%d",num);
  1846.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_dl,VTYPE_BOOL,optionname,OPT_SINGLE);
  1847.  
  1848.             sprintf(optionname,"AllowBatch_%d",num);
  1849.             HBBS_GetSetting(ProtocolListFile,(void *)&pnode->allow_batch,VTYPE_BOOL,optionname,OPT_SINGLE);
  1850.  
  1851.             // Add Completed protocol node to the list of protocols
  1852.  
  1853.             AddTail(BBSGlobal->ProtocolList,(struct Node *)pnode);
  1854.  
  1855.             num++;
  1856.             sprintf(optionname,"Name_%d",num);
  1857.             error=FALSE;
  1858.           }
  1859.         }
  1860.  
  1861.  
  1862.       }
  1863.       // free temp string..
  1864.  
  1865.       FreeStr(tmpstr);
  1866.  
  1867.     }
  1868.  
  1869.     // free config..
  1870.  
  1871.     HBBS_FlushConfig(ProtocolListFile);
  1872.   }
  1873.   else HBBS_DoErrorMessage(EMSG_PROTOCOLSFILEERROR,0,NULL);
  1874.  
  1875.   // Set the amount of protocols loaded
  1876.  
  1877.   BBSGlobal->Protocols=num-1;
  1878.  
  1879.   // if no protocols were loaded the return false!
  1880.   return((BOOL)(BBSGlobal->Protocols ? TRUE : FALSE));
  1881. }
  1882.  
  1883. void FreeProtocols( void )
  1884. {
  1885.   struct ProtocolNode *pnode;
  1886.  
  1887.   if (BBSGlobal->ProtocolList)
  1888.   {
  1889.     while (BBSGlobal->ProtocolList->lh_Head->ln_Succ)
  1890.     {
  1891.       pnode=(struct ProtocolNode *)BBSGlobal->ProtocolList->lh_Head;
  1892.       FreeStr(pnode->node.ln_Name);
  1893.       FreeStr(pnode->modulename);
  1894.       FreeStr(pnode->moduleopts);
  1895.       Remove((struct Node *)pnode);
  1896.       FreeVec(pnode);
  1897.     }
  1898.     FreeVec(BBSGlobal->ProtocolList);
  1899.   }
  1900.  
  1901. }
  1902.  
  1903. BOOL CheckBBSGlobal( void )
  1904. {
  1905.   BOOL retval=TRUE;
  1906.   if (BBSGlobal->BBSName==NULL ||
  1907.       BBSGlobal->BBSNodes==0 ||
  1908.       BBSGlobal->Drive==NULL ||
  1909.       BBSGlobal->BBSDrive==NULL)
  1910.   {
  1911.     HBBS_DoErrorMessage(EMSG_BBSGLOBALERR,0,NULL);
  1912.     retval=FALSE;
  1913.   }
  1914.  
  1915.   if (HBBS_NodesInList(BBSGlobal->ButtonName)!=HBBS_NodesInList(BBSGlobal->ButtonCMD))
  1916.   {
  1917.     FreeStrList(BBSGlobal->ButtonName);
  1918.     BBSGlobal->ButtonName=NULL;
  1919.     FreeStrList(BBSGlobal->ButtonCMD);
  1920.     BBSGlobal->ButtonCMD=NULL;
  1921.  
  1922.   }
  1923.   return(retval);
  1924. }
  1925.  
  1926. BOOL InitGlobal( void )
  1927. {
  1928.   if (LoadBBSGlobalData(FILE_BBSGLOBAL,BBSGlobal)==TYPE_NONE)
  1929.   {
  1930.     if (LoadScreenPrefs())
  1931.     {
  1932.       // *C* check required setting.. also need to check for valid assigns on the drives..
  1933.       // must also check config pairs match up.. (e.g. LanguageName/Extn)
  1934.       if (CheckBBSGlobal())
  1935.       {
  1936.         if (HBBS_FindTotalUsers()>=0)
  1937.         {
  1938.           if (LoadLevels())
  1939.           {
  1940.             if (LoadProtocols())
  1941.             {
  1942.               return(TRUE);
  1943.             }
  1944.           }
  1945.         }
  1946.       }
  1947.     }
  1948.   }
  1949.   return(FALSE);
  1950. }
  1951.  
  1952. void FreeGlobal( void )
  1953. {
  1954.   FreeProtocols();
  1955.   FreeLevels();
  1956.   FreeBBSGlobalData(BBSGlobal);
  1957. }
  1958.  
  1959. BOOL InitNodes( void )
  1960. {
  1961.   // Read Settings to be used as a default for all nodes.
  1962.   if (LoadNodeSettingsData(NODE_GLOBAL,&BBSGlobal->NodeGlobalData->NodeSettings)==TYPE_NONE)
  1963.   {
  1964.     // create list of nodes..
  1965.     if (CreateNodeList())
  1966.     {
  1967.       // *C* we need to check that all the required settings for the node have been
  1968.       // set and to set other values to defaults..
  1969.       return(TRUE);
  1970.     }
  1971.   }
  1972.   FreeNodeSettingsData(&BBSGlobal->NodeGlobalData->NodeSettings);
  1973.  
  1974.   return(FALSE);
  1975. }
  1976.  
  1977. BOOL InitConferences( void )
  1978. {
  1979.   if (CreateConfList())
  1980.   {
  1981.     if (CheckConfPaths()) return(TRUE);
  1982.   }
  1983.   return(FALSE);
  1984. }
  1985.  
  1986. void FreeConferences( void )
  1987. {
  1988.   FreeConfList();
  1989. }
  1990.  
  1991. int main(int argc,char **argv)
  1992. {
  1993.   WB2CLI((struct WBStartup *)argv,4000,DOSBase);  /* so you get the default path! */
  1994.   CtrlProc=(struct Process *)FindTask (NULL); // can this fail ?? :-)
  1995.   init();
  1996.  
  1997.   OpenLoadingWindow();
  1998.   if (AssignOK("HBBS:"))
  1999.   {
  2000.     if (InitGlobal())
  2001.     {
  2002.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,"Starting Control Program",TYPE_DONTCARE);
  2003.       if (InitNodes())
  2004.       {
  2005.         HBBS_GetDate(BBSGlobal->LastCalledDate);
  2006.         if (InitConferences())
  2007.         {
  2008.           if (LoadPrivateData())
  2009.           {
  2010.             HBBS_LoadCallsData();
  2011.             CtrlMain();
  2012.             HBBS_SaveCallsData();
  2013.           }
  2014.         }
  2015.       //  HBBS_rterror("Freeing Conferences");
  2016.         FreeConferences();
  2017.     //    HBBS_rterror("Freeing Node Settings Data");
  2018.         FreeNodeSettingsData(&BBSGlobal->NodeGlobalData->NodeSettings);
  2019.       }
  2020.   //    HBBS_rterror("Freeing Nodes");
  2021.       FreeNodeList();
  2022.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,"Stopping Control Program",TYPE_DONTCARE);
  2023.     }
  2024. //    HBBS_rterror("Freeing Global");
  2025.     FreeGlobal(); // we call FreeGlobal even if InitGlobal fails..
  2026.   }
  2027.   else
  2028.   HBBS_DoErrorMessage(EMSG_NOHBBS,0,NULL);
  2029. //  HBBS_rterror("Cleanup");
  2030.   HBBS_SetBBS(NULL); // so that if the lib is still in memory utils won't work anymore..
  2031.   cleanup(NULL);
  2032. }
  2033.